# 版本: 1.0.0
# 作者: 陈振玺
# 功能: 大语言模型客户端，支持邮件措辞优化

import json
import requests
from typing import Dict, Any, Optional, List
from .config import LLMConfig


class LLMClient:
    """大语言模型客户端"""
    
    def __init__(self, config: LLMConfig):
        """初始化LLM客户端
        
        Args:
            config: LLM配置对象
        """
        self.config = config
        self.session = requests.Session()
        self.session.headers.update({
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {config.api_key}'
        })
    
    def _make_request(self, messages: List[Dict[str, str]]) -> Dict[str, Any]:
        """发送API请求
        
        Args:
            messages: 消息列表
            
        Returns:
            API响应结果
            
        Raises:
            Exception: API请求失败时抛出异常
        """
        payload = {
            'model': self.config.model,
            'messages': messages,
            'max_tokens': self.config.max_tokens,
            'temperature': self.config.temperature
        }
        
        try:
            response = self.session.post(
                f"{self.config.api_url.rstrip('/')}/chat/completions",
                json=payload,
                timeout=30
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            raise Exception(f"LLM API请求失败: {e}")
        except json.JSONDecodeError as e:
            raise Exception(f"LLM API响应解析失败: {e}")
    
    def optimize_email_content(self, 
                             original_content: str, 
                             subject: str = "",
                             recipient_info: str = "",
                             tone: str = "professional") -> str:
        """优化邮件内容
        
        Args:
            original_content: 原始邮件内容
            subject: 邮件主题
            recipient_info: 收件人信息
            tone: 邮件语调 (professional, friendly, formal, casual)
            
        Returns:
            优化后的邮件内容
            
        Raises:
            Exception: 优化失败时抛出异常
        """
        # 构建优化提示词
        system_prompt = self._build_optimization_prompt(tone)
        user_prompt = self._build_user_prompt(original_content, subject, recipient_info)
        
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ]
        
        try:
            response = self._make_request(messages)
            
            if 'choices' not in response or not response['choices']:
                raise Exception("LLM API返回格式错误")
            
            optimized_content = response['choices'][0]['message']['content'].strip()
            return optimized_content
            
        except Exception as e:
            raise Exception(f"邮件内容优化失败: {e}")
    
    def _build_optimization_prompt(self, tone: str) -> str:
        """构建优化提示词
        
        Args:
            tone: 邮件语调
            
        Returns:
            系统提示词
        """
        tone_descriptions = {
            "professional": "专业、正式、商务化",
            "friendly": "友好、亲切、温和",
            "formal": "正式、严谨、礼貌",
            "casual": "轻松、随意、自然"
        }
        
        tone_desc = tone_descriptions.get(tone, "专业、正式")
        
        return f"""
你是一个专业的邮件写作助手。你的任务是优化用户提供的邮件内容，使其更加{tone_desc}。

优化要求：
1. 保持原意不变，只改进表达方式
2. 语言要{tone_desc}
3. 结构清晰，逻辑合理
4. 语法正确，用词准确
5. 适当调整语句长度和段落结构
6. 如果原文有明显的语法错误或表达不当，请修正
7. 保持邮件的核心信息和关键细节

请直接返回优化后的邮件内容，不要添加任何解释或说明。
"""
    
    def _build_user_prompt(self, content: str, subject: str, recipient_info: str) -> str:
        """构建用户提示词
        
        Args:
            content: 邮件内容
            subject: 邮件主题
            recipient_info: 收件人信息
            
        Returns:
            用户提示词
        """
        prompt_parts = []
        
        if subject:
            prompt_parts.append(f"邮件主题：{subject}")
        
        if recipient_info:
            prompt_parts.append(f"收件人信息：{recipient_info}")
        
        prompt_parts.append(f"邮件内容：\n{content}")
        
        return "\n\n".join(prompt_parts)
    
    def optimize_subject(self, original_subject: str, content: str = "") -> str:
        """优化邮件主题
        
        Args:
            original_subject: 原始主题
            content: 邮件内容（可选，用于更好地理解上下文）
            
        Returns:
            优化后的主题
            
        Raises:
            Exception: 优化失败时抛出异常
        """
        system_prompt = """
你是一个专业的邮件主题优化助手。你的任务是优化邮件主题，使其更加简洁、准确、吸引人。

优化要求：
1. 主题要简洁明了，一般不超过50个字符
2. 准确反映邮件的核心内容
3. 使用恰当的关键词
4. 避免使用过于夸张或营销性的词汇
5. 保持专业性

请直接返回优化后的主题，不要添加任何解释或说明。
"""
        
        user_prompt = f"原始主题：{original_subject}"
        if content:
            user_prompt += f"\n\n邮件内容：\n{content[:500]}..."  # 限制内容长度
        
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ]
        
        try:
            response = self._make_request(messages)
            
            if 'choices' not in response or not response['choices']:
                raise Exception("LLM API返回格式错误")
            
            optimized_subject = response['choices'][0]['message']['content'].strip()
            return optimized_subject
            
        except Exception as e:
            raise Exception(f"邮件主题优化失败: {e}")
    
    def generate_email_content(self, 
                             purpose: str,
                             key_points: List[str],
                             recipient_info: str = "",
                             tone: str = "professional") -> str:
        """生成邮件内容
        
        Args:
            purpose: 邮件目的
            key_points: 关键要点列表
            recipient_info: 收件人信息
            tone: 邮件语调
            
        Returns:
            生成的邮件内容
            
        Raises:
            Exception: 生成失败时抛出异常
        """
        tone_descriptions = {
            "professional": "专业、正式、商务化",
            "friendly": "友好、亲切、温和",
            "formal": "正式、严谨、礼貌",
            "casual": "轻松、随意、自然"
        }
        
        tone_desc = tone_descriptions.get(tone, "专业、正式")
        
        system_prompt = f"""
你是一个专业的邮件写作助手。你的任务是根据用户提供的信息生成一封{tone_desc}的邮件。

写作要求：
1. 语言要{tone_desc}
2. 结构清晰，包含适当的开头、正文和结尾
3. 涵盖所有关键要点
4. 语法正确，用词准确
5. 长度适中，不要过于冗长
6. 符合邮件写作规范

请直接返回邮件内容，不要添加任何解释或说明。
"""
        
        user_prompt_parts = [f"邮件目的：{purpose}"]
        
        if key_points:
            user_prompt_parts.append("关键要点：")
            for i, point in enumerate(key_points, 1):
                user_prompt_parts.append(f"{i}. {point}")
        
        if recipient_info:
            user_prompt_parts.append(f"收件人信息：{recipient_info}")
        
        user_prompt = "\n".join(user_prompt_parts)
        
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ]
        
        try:
            response = self._make_request(messages)
            
            if 'choices' not in response or not response['choices']:
                raise Exception("LLM API返回格式错误")
            
            generated_content = response['choices'][0]['message']['content'].strip()
            return generated_content
            
        except Exception as e:
            raise Exception(f"邮件内容生成失败: {e}")
    
    def test_connection(self) -> bool:
        """测试LLM API连接
        
        Returns:
            连接是否成功
        """
        try:
            messages = [
                {"role": "user", "content": "Hello, this is a test message."}
            ]
            
            response = self._make_request(messages)
            return 'choices' in response and len(response['choices']) > 0
            
        except Exception:
            return False
    
    def get_usage_info(self) -> Dict[str, Any]:
        """获取API使用信息（如果支持）
        
        Returns:
            使用信息字典
        """
        # 这个功能依赖于具体的API提供商
        # 这里提供一个基础实现
        return {
            "model": self.config.model,
            "api_url": self.config.api_url,
            "max_tokens": self.config.max_tokens,
            "temperature": self.config.temperature
        }